﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PropertyChangeUndoEvent.cs" >
//   J. Prinz
// </copyright>
// <summary>
//   A PropertyChangeUndoEvent holds all data to redo and undo PropertyChanges
//   for any Property of a Target. The Class uses reflection to set Property Values
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace AutomationMLMapper.Utilities
{
    /// <summary>
    ///   A PropertyChangeUndoEvent holds all data to redo and undo PropertyChanges
    ///   for any Property of a Target. The Class uses reflection to set Property Values
    /// </summary>
    public class PropertyChangeUndoEvent : IUndoEvent
    {
        #region Fields

        /// <summary>
        ///  new value for property
        /// </summary>
        private readonly object newValue;

        /// <summary>
        ///  old and saved value for property
        /// </summary>
        private readonly object oldValue;

        /// <summary>
        ///  The property name.
        /// </summary>
        private readonly string propertyName;

        /// <summary>
        ///  The target object, which owns the property
        /// </summary>
        private readonly object target;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyChangeUndoEvent"/> class. 
        /// </summary>
        /// <param name="target">
        /// The target object, which owns the property
        /// </param>
        /// <param name="propertyName">
        /// The property name. 
        /// </param>
        /// <param name="oldValue">
        /// The old value. 
        /// </param>
        /// <param name="newValue">
        /// The new value. 
        /// </param>
        public PropertyChangeUndoEvent(object target, string propertyName, object oldValue, object newValue)
        {
            this.target = target;
            this.propertyName = propertyName;
            this.oldValue = oldValue;
            this.newValue = newValue;
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// redo sets the New Value
        /// </summary>
        public void Redo()
        {
            this.SetValue(this.newValue);
        }

        /// <summary>
        /// undo sets the Old Value
        /// </summary>
        public void Undo()
        {
            this.SetValue(this.oldValue);
        }

        #endregion

        #region Methods

        /// <summary>
        /// set property value with reflection
        /// </summary>
        /// <param name="value">
        /// The value. 
        /// </param>
        private void SetValue(object value)
        {
            // Set Value on the _target using reflection (_propertyName)
            var inf = this.target.GetType().GetProperty(this.propertyName);
            if (inf != null)
            {
                inf.SetValue(this.target, value, null);
            }
        }

        #endregion
    }
}